/*
 * @Author: 邱狮杰
 * @Date: 2021-05-14 23:36:39
 * @LastEditTime : 2021-05-20 17:07:37
 * @FilePath     : /wedding-dress-selection/src/page/main/index.tsx
 * @Description: entry
 */
import { FC, useState, useRef, useEffect, useContext } from 'react'
import SwiperCore, { Virtual } from 'swiper'
import { Canceler } from 'axios'
import { message, Skeleton } from 'antd'
import { MessageType } from 'antd/es/message/index'
import { useHistory } from 'react-router-dom'
import { App, BackgroundImg, SelectMask } from './styledComponents'
import { Swiper, SwiperSlide } from 'swiper/react'
import SwiperClass from 'swiper/types/swiper-class'
import { useMounted, useUnload, useGetOpenid } from '../../hook/index'
import { useCannelRef, useUserInfoForReducer, useLikeForReducer, useWeddingForReducer } from '../../hook/index'
// import {} from 'react-router-dom'
// import "./index.scss";
// import BackgroundMain from '../../assets/backgroundMain.png'
import Button from '../../components/button/index'
import Select from '../../components/select/index'
import check from '../../assets/check.png'
import noCheck from '../../assets/noCheck.png'
import whiteArrow from '../../assets/whiteArrow.png'
import FlexAuxiliary from '../../components/layout/flexAuxiliarys'
import FlyingLove from '../../components/flyingLove/index'
import { useTitleContextType, CreateTitle, useContextCategoryContextType, CreateCategoryContext } from '../../reducer/index'
import { SynchronizationAwaitError, sendLikeRequest, getLocal } from '../../utils/index'
import { realData, ExhibitionConf } from './utils'
import { BaseRequest } from '../../http/index'
import { OPENID } from '../../reducer/userInfo'
let warn: MessageType | null = null

export interface transferConf {
  name: string
}
type Props = {}
SwiperCore.use([Virtual])
const Main: FC<Props> = () => {
  const his = useHistory()
  useGetOpenid(() => {})
  const { titleState } = useContext(CreateTitle) as useTitleContextType
  const { CategoryState } = useContext(CreateCategoryContext) as useContextCategoryContextType
  const { userInfoState, userInfoDispatch } = useUserInfoForReducer()
  const { weddingDispatch } = useWeddingForReducer()
  const { likeDispatch } = useLikeForReducer()
  const cannelRef = useCannelRef()
  let cannel: Canceler | null = null
  // 当前的pageNum
  const curRealTimeIndex = useRef<number>(1)
  const curRealData = useRef<ExhibitionConf[]>()
  // 上一次的pageNum
  const [curIndex, setCurIndex] = useState(1)
  // 是否选中爱心
  const [isCheck, setIsCheck] = useState(false)
  // 是否双击确认选中爱心
  const [doubleClickCheck, setDoubleClickCheck] = useState(false)

  // 是否隐藏提示消息
  const [showAlertMessage, setShowAlertMessage] = useState(true)
  const [realData, setTestData] = useState<ExhibitionConf[]>([])
  // 心仪款式的数量
  const [favoriteStyleNum, setFavoriteStyleNum] = useState(realData.filter(item => item.like).length)
  let timeOut: NodeJS.Timeout | null = null
  useMounted(() => {
    timeOut = setTimeout(() => {
      setShowAlertMessage(false)
    }, 2000)
  })
  useUnload(() => {
    if (timeOut && timeOut?.hasRef?.()) timeOut.unref()
  })
  useMounted(async () => {
    // 初始化数据
    const [err, res] = await SynchronizationAwaitError(
      BaseRequest({
        url: '/invitation-goods',
        params: { category_id: CategoryState.id, invitation_id: userInfoState.invitationId as string },
        cancelToken: new cannelRef.current(function (e) {
          cannel = e
        }),
      }),
      (e: realData) => {
        return e.data.data.map<ExhibitionConf>(item => {
          return { id: item.id, pic: item.thumb, like: userInfoState.likes.includes(item.id.toString()) }
        })
      }
    )
    !err && setTestData(res as unknown as ExhibitionConf[])
  })
  useUnload(() => {
    // 取消正在发送的数据
    if (cannel) cannel()
  })
  useEffect(() => {
    setFavoriteStyleNum(realData.filter(item => item.like).length)
  }, [isCheck, realData])

  function addSwiperScroll() {
    curRealTimeIndex.current++
    setCurIndex(curRealTimeIndex.current)
    setIsCheck(realData[curRealTimeIndex.current - 1].like)
    if (doubleClickCheck) setDoubleClickCheck(false)
  }

  function redSwiperScroll() {
    curRealTimeIndex.current--
    setCurIndex(curRealTimeIndex.current)
    setIsCheck(realData[curRealTimeIndex.current - 1].like)
    if (doubleClickCheck) setDoubleClickCheck(false)
  }

  function doubleClickLike(e: SwiperClass) {
    let cur = realData[e.activeIndex]
    cur.like = !cur.like
    setTestData(val => {
      val[e.activeIndex] = cur
      curRealData.current = val
      return [...val]
    })
    setIsCheck(curRealData.current![e.activeIndex]!.like)
    if (curRealData.current![e.activeIndex]!.like) {
      setDoubleClickCheck(true)
      userInfoDispatch({ type: 'likesAdd', data: curRealData.current![e.activeIndex].id.toString() })
    } else {
      setDoubleClickCheck(false)
      // 删除缓存中的likes
      const idx = userInfoState.likes.findIndex(item => item === cur.id.toString())
      const backup = userInfoState.likes
      if (idx !== -1) {
        if (idx === 0) backup.shift()
        else backup.splice(1, idx)
      }
      userInfoDispatch({ type: 'editLikes', data: backup })
    }
  }
  async function iLike() {
    if (!favoriteStyleNum) {
      if (warn) warn()
      warn = message.warning('您还并没有选择')
      return
    }
    // 跳转前保存当前所有数据
    const likeData = realData.filter(item => item.like).map(item => ({ edit: false, check: false, designSrc: Array.isArray(item.pic) ? item.pic[0] : item.pic, id: item.id }))
    // const LikeDataId = Array.from(new Set(likeData.map(item => item.id.toString()).concat(...userInfoState.likes)))
    likeDispatch({ type: 'reset', data: likeData })
    weddingDispatch({ type: 'reset', data: realData })
    his.push('/select')
    // const [err, res] = await sendLikeRequest(userInfoState.invitationId.toString(), userInfoState.openId.toString(), LikeDataId.join(','))
    // if (res.code === 200) {
    // } else {
    //   console.log(err, 'errMainSend')
    // }
  }

  async function end() {
    const [_, res] = await sendLikeRequest(userInfoState.invitationId as string, userInfoState.openId || (getLocal(OPENID) as string), userInfoState.likes.join(','))
    if (res.code === 200) his.push('/end')
  }
  if (!realData.length)
    return (
      <>
        <Skeleton />
        <Skeleton />
      </>
    )
  return (
    <App>
      <FlexAuxiliary style={{ top: '3%', padding: '0 10px', zIndex: 110, justifyContent: 'space-between' }}>
        <Select content={titleState.name} onProxyClick={() => his.push('/category')} style={{ color: 'white' }} arrowImg={whiteArrow} />
        <div className='curCard'>
          {curIndex}/{realData.length}
        </div>
        <img className='checkImg' src={isCheck ? check : noCheck} alt={'check'} />
      </FlexAuxiliary>
      <Swiper
        onInit={() => {
          if (realData[0].like) setIsCheck(true)
        }}
        onDoubleClick={doubleClickLike}
        onTouchEnd={(e: any, event: any) => {
          if (!e.swipeDirection) return
          // 这里必须使用一个定时器，因为e.activeIndex为当前触发值，并不能正确的同步当前值，这也和react hooks只渲染当前值有关, 所以应该通过一个宏任务跳过批处理获取当前最新值
          setTimeout(() => {
            if (!(curRealTimeIndex.current - 1 === e.activeIndex)) {
              e.swipeDirection === 'next' ? addSwiperScroll() : redSwiperScroll()
            }
          }, 0)
        }}
        lazy
        // onSlideNextTransitionStart={addSwiperScroll}
        // onSlidePrevTransitionStart={redSwiperScroll}
        virtual={{ cache: true, addSlidesAfter: 1, addSlidesBefore: 1 }}
        observer
        observeParents
        observeSlideChildren
        style={{ height: '100vh', width: '100vw' }}>
        {realData.map((realDataItem, realIndex) => {
          if (Array.isArray(realDataItem.pic)) {
            return (
              <SwiperSlide virtualIndex={realIndex} style={{ height: '100vh' }} key={`${realIndex}newSwiper`}>
                <Swiper
                  direction={'vertical'}
                  style={{
                    height: '100vh',
                    width: '100vw',
                  }}>
                  {realDataItem.pic.map((picItem, picIndex) => {
                    return (
                      <SwiperSlide style={{ height: '100vh' }} key={picIndex}>
                        <BackgroundImg>
                          <img src={picItem} alt={'antd'} />
                        </BackgroundImg>
                      </SwiperSlide>
                    )
                  })}
                </Swiper>
              </SwiperSlide>
            )
          }
          return (
            <SwiperSlide virtualIndex={realIndex} style={{ height: '100vh' }} key={realIndex + 1}>
              <BackgroundImg>
                <img src={realDataItem.pic} alt={'antd'} />
              </BackgroundImg>
            </SwiperSlide>
          )
        })}
      </Swiper>
      <SelectMask style={showAlertMessage ? { transform: 'translate(-50%, -50%) scale(1)' } : { transform: 'translate(-50%, -50%) scale(0)' }} className='selectMask'>
        左右滑动切换款式
        <br />
        双击图片可添加到心仪
      </SelectMask>
      <FlexAuxiliary style={{ bottom: '2%' }}>
        <Button onProxyClick={iLike} style={{ background: 'rgba(255,255,255,0.8)', color: '#222' }} content={`我喜欢的${!favoriteStyleNum ? '' : '(' + favoriteStyleNum + ')'}`} />
        <Button onProxyClick={end} content='结束选纱' />
      </FlexAuxiliary>
      <FlyingLove run={doubleClickCheck} />
    </App>
  )
}

export default Main
